﻿using Camc.Quality.Bop.UnifyDto;
using Abp.Domain.Repositories;
using Camc.Quality.Quality;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Text;
using System.Threading.Tasks;
using Camc.Quality.Authorization.Users;
using Abp.Application.Services.Dto;
using Abp.Extensions;
using Abp.Linq.Extensions;
using Microsoft.EntityFrameworkCore;
using System.Reflection;
using System.ComponentModel;
using Camc.Quality.Bop.TreeObject;
using Camc.Quality.Bop.Dto;
using Camc.Quality.Dto.QualityPlatformDto;
using Camc.Quality.QualityAnalysis.RTechniqueEntity;
using Camc.Quality.RecordTable.FormBase;
using Camc.Quality.ProcessRoute;
using Abp.UI;
using Camc.Quality.DataDictionary;
using Microsoft.AspNetCore.Http;
using Camc.Quality.Common;
using System.IO;
using System.Security.Cryptography;
using ICSharpCode.SharpZipLib.Zip;
using Camc.Quality.Dto.TableReturnDto.Technique;
using Camc.Quality.ITech;
using Camc.Quality.RecordTable.FormClass;
using Camc.Quality.StoreManagement.StoragePut;
using Abp.Collections.Extensions;
using Abp.Domain.Uow;

namespace Camc.Quality.Bop
{
    public class BopUnifyAppService : QualityAppServiceBase
    {
        public List<TreeClass> treeNodes = new List<TreeClass>();
        private readonly IRepository<BopNode, Guid> _bopNodeRepository;
        private readonly IRepository<BopDesc, Guid> _bopDescRepository;
        private readonly IRepository<TechniqueEntity, Guid> _techniqueEntityRepository;
        private readonly IRepository<ProcessesEntity, Guid> _processesEntityRepository;
        private readonly IRepository<WorkStepEntity, Guid> _workStepEntityRepository;
        private readonly IRepository<User, long> _userRepository;
        private readonly IRepository<RbopNode, Guid> _rBopNodeRepository;
        private readonly IRepository<RTechniqueEntity, Guid> _rTechniqueEntityRepository;
        private readonly IRepository<TableBase, Guid> _tableBaseEntity;
        private readonly IRepository<ConvertFormBase, Guid> _convertFormBaseEntity;
        private readonly IRepository<ProcessLine, Guid> _processLineRepository;
        private readonly IRepository<Sys_Code, Guid> _sysCodeRepository;
        private readonly ITechProcess _techProcess;
        private readonly IRepository<TreeVersionLog, int> _treeVersionLogRepository;
        private readonly IRepository<LoadPieceEntity, Guid> _loadPieceRepository;
        private readonly IRepository<MakeResourcesEntity, Guid> _makeResourcesEntityRepository;
        private readonly IRepository<VideoEntity, Guid> _videoEntityRepository;
        private readonly IUnitOfWorkManager _unitOfWorkManager;
        public BopUnifyAppService(IRepository<TableBase, Guid> tableBaseEntity,
            ITechProcess techProcess,
                                  IRepository<ConvertFormBase, Guid> convertFormBaseEntity,
                                  IRepository<ProcessLine, Guid> processLineRepository,
                                  IRepository<BopNode, Guid> bopNodeRepository,
                                  IRepository<BopDesc, Guid> bopDescRepository,
                                  IRepository<TechniqueEntity, Guid> techniqueEntityRepository,
                                  IRepository<ProcessesEntity, Guid> processesEntityRepository,
                                  IRepository<WorkStepEntity, Guid> workStepEntityRepository,
                                  IRepository<User, long> userRepository,
                                  IRepository<RbopNode, Guid> rBopNodeRepository,
                                  IRepository<RTechniqueEntity, Guid> rTechniqueEntityRepository,
                                  IRepository<Sys_Code, Guid> sysCodeRepository,
                                  IRepository<TreeVersionLog, int> treeVersionLogRepository,
                                  IRepository<LoadPieceEntity, Guid> loadPieceRepository,
                                  IRepository<MakeResourcesEntity, Guid> makeResourcesEntityRepository,
                                  IRepository<VideoEntity, Guid> videoEntityRepository,
                                  IUnitOfWorkManager unitOfWorkManager
                                  )

        {
            _techProcess = techProcess;
            _tableBaseEntity = tableBaseEntity;
            _bopNodeRepository = bopNodeRepository;
            _processLineRepository = processLineRepository;
            _bopDescRepository = bopDescRepository;
            _techniqueEntityRepository = techniqueEntityRepository;
            _processesEntityRepository = processesEntityRepository;
            _workStepEntityRepository = workStepEntityRepository;
            _userRepository = userRepository;
            _rBopNodeRepository = rBopNodeRepository;
            _rTechniqueEntityRepository = rTechniqueEntityRepository;
            _convertFormBaseEntity = convertFormBaseEntity;
            _sysCodeRepository = sysCodeRepository;
            _treeVersionLogRepository = treeVersionLogRepository;
            _loadPieceRepository = loadPieceRepository;
            _makeResourcesEntityRepository = makeResourcesEntityRepository;
            _videoEntityRepository = videoEntityRepository;
            _unitOfWorkManager = unitOfWorkManager;
        }
        /// <summary>
        /// 文件编号模糊查询
        /// </summary>
        /// <param name="techniqueNumberStr"></param>
        /// <returns></returns>
        public async Task<List<string>> GetTechniqueNumberList(string techniqueNumberStr)
        {
            List<string> techniqueNumberList = new List<string>();
            var techList = await _techniqueEntityRepository.GetAllListAsync(d => !string.IsNullOrEmpty(d.TechniqueNumber));
            var result = (from cc in techList
                          select cc.TechniqueNumber);

            if (result.Count() > 0)
            {
                result = result.WhereIf(!string.IsNullOrEmpty(techniqueNumberStr), d => d.Contains(techniqueNumberStr));
                techniqueNumberList = result.Distinct().ToList();
            }
            return techniqueNumberList;
        }

        /// <summary>
        /// 图号模糊查询
        /// </summary>
        /// <param name="moduleCodeStr"></param>
        /// <returns></returns>
        public async Task<List<string>> GetModuleCodeList(string moduleCodeStr)
        {
            List<string> moduleList = new List<string>();
            var techList = await _techniqueEntityRepository.GetAllListAsync(d => !string.IsNullOrEmpty(d.ModuleCode));
            var result = (from cc in techList
                          select cc.ModuleCode);

            if (result.Count() > 0)
            {
                result = result.WhereIf(!string.IsNullOrEmpty(moduleCodeStr), d => d.Contains(moduleCodeStr));
                moduleList = result.Distinct().ToList();
            }
            return moduleList;
        }
        /// <summary>
        /// 型号模糊查询
        /// </summary>
        /// <param name="productCodeStr"></param>
        /// <returns></returns>
        public async Task<List<string>> GetProductCodeList(string productCodeStr)
        {
            List<string> productList = new List<string>();
            var techList = await _techniqueEntityRepository.GetAllListAsync(d => !string.IsNullOrEmpty(d.ProductCode));
            var result = (from cc in techList
                          select cc.ProductCode);

            if (result.Count() > 0)
            {
                result = result.WhereIf(!string.IsNullOrEmpty(productCodeStr), d => d.Contains(productCodeStr));
                productList = result.Distinct().ToList();
            }
            return productList;
        }
        /// <summary>
        /// 工艺规程查询接口
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public PagedResultDto<BopUnifyDto> GetBopUnifyList(GetBopUnifyListInput input)
        {
            //查找不是变更状态的工艺规程
            var techList = (from cc in _techniqueEntityRepository.GetAll().WhereIf(!string.IsNullOrEmpty(input.TechniqueNumber), d => d.TechniqueNumber.Contains(input.TechniqueNumber))
                           .WhereIf(!string.IsNullOrEmpty(input.ModuleCode), d => d.ModuleCode.Contains(input.ModuleCode)).WhereIf(!string.IsNullOrEmpty(input.ProductCode), d => d.ProductCode.Contains(input.ProductCode))
                            where cc.FileStatus != FileStatus.变更中
                            select cc
                            );
            if (techList.Count() > 0)
            {
                int count = techList.Count();
                var ff = techList.ToList();
                if (input.Sorting == "Default")
                {
                    ff = techList.OrderByDescending(d => d.CreationTime).ThenByDescending(d => d.TechniqueNumber).ThenBy(d => d.Edition).AsQueryable().PageBy(input).AsNoTracking().ToList();

                }
                else
                {
                    ff = techList.OrderBy(input.Sorting).AsQueryable().PageBy(input).AsNoTracking().ToList();
                }
                if (ff.Count > 0)
                {
                    List<BopUnifyDto> tt = new List<BopUnifyDto>();
                    for (int i = 0; i < ff.Count; i++)
                    {
                        BopUnifyDto ufo = new BopUnifyDto();
                        ufo.Id = ff[i].Id;
                        ufo.TechniqueNumber = ff[i].TechniqueNumber;
                        ufo.TechniqueName = ff[i].TechniqueName;
                        ufo.Version = ff[i].TechniqueNumber.Right(2);
                        ufo.ModuleCode = ff[i].ModuleCode;
                        ufo.ModuleName = ff[i].ModuleName;
                        ufo.ProductCode = ff[i].ProductCode;
                        ufo.StageSign = ff[i].StageSign;
                        ufo.StageSignDesc = GetEnumDesc(ff[i].StageSign);
                        ufo.TechniqueAuthor = ff[i].TechniqueAuthor;
                        ufo.TechniqueAuthorTime = ff[i].TechniqueAuthor;
                        ufo.Proofreader = ff[i].Proofreader;
                        ufo.ProofreaderTime = ff[i].ProofreaderTime;
                        ufo.Reviewer = ff[i].Reviewer;
                        ufo.ReviewerTime = ff[i].ReviewerTime;
                        ufo.Inspector = ff[i].Inspector;
                        ufo.InspectorTime = ff[i].InspectorTime;
                        ufo.Certifier = ff[i].Certifier;
                        ufo.CertifierTime = ff[i].CertifierTime;
                        ufo.CompileTime = ff[i].CompileTime;
                        if (ff[i].Property != null)
                        {
                            ufo.Property = ff[i].Property.Value;
                            ufo.PropertyDesc = GetEnumDesc(ff[i].Property);
                        }
                        ufo.CreationTime = ff[i].CreationTime;
                        ufo.Edition = ff[i].Edition;
                        ufo.FileStatus = ff[i].FileStatus;
                        ufo.FileStatusDesc = GetEnumDesc(ff[i].FileStatus);
                        ufo.LotNo = GetLotNoByTechId(ff[i].Id);
                        tt.Add(ufo);
                    }

                    return new PagedResultDto<BopUnifyDto>(count, tt);
                }
                else
                {
                    return new PagedResultDto<BopUnifyDto>();
                }
            }
            else
            {
                return new PagedResultDto<BopUnifyDto>();
            }
        }
        /// <summary>
        /// 根据Guid获取发次
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public string GetLotNoByTechId(Guid id)
        {
            var node = _bopNodeRepository.FirstOrDefault(d => d.TechniqueEntityId == id);
            if (node != null)
            {
                var lotNoId = _bopDescRepository.FirstOrDefault(d => d.Id == node.BopDescId).LotNoId;
                if (lotNoId != null)
                {
                    var lotNo = _sysCodeRepository.FirstOrDefault(s => s.Id == lotNoId);
                    if (lotNo != null)
                    {
                        return lotNo.Description;
                    }
                    else
                    {
                        return "";
                    }
                }
                else
                {
                    return "";
                }
            }
            else
            {
                return "";
            }
        }
        /// <summary>
        /// 根据Id获取工艺单个信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public TechniqueEntityReturnDto GetTechniqueByNumber(Guid id)
        {
            var temp = _techniqueEntityRepository.GetAll().Where(d => d.Id == id).FirstOrDefault();
            return ObjectMapper.Map<TechniqueEntityReturnDto>(temp);
        }
        public static String GetEnumDesc(Enum e)
        {

            FieldInfo EnumInfo = e.GetType().GetField(e.ToString());
            if (EnumInfo == null)
            {
                return "";
            }
            DescriptionAttribute[] EnumAttributes
                = (DescriptionAttribute[])EnumInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);
            if (EnumAttributes.Length > 0)
            {
                return EnumAttributes[0].Description;
            }
            return e.ToString();
        }
        /// <summary>
        /// 根据Id获取工艺规程信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<BopContentInfoDto> GetBopUnifyInfoByNumber(Guid id)
        {
            var bopContentInfo = new BopContentInfoDto();
            var tech = _techniqueEntityRepository.FirstOrDefault(x => x.Id == id);
            var bopNode = _bopNodeRepository.FirstOrDefault(x => x.TechniqueEntityId == id);
            if (bopNode == null)
            {
                if (tech != null)
                {
                    bopContentInfo.ProcessName = tech.TechniqueName;
                    bopContentInfo.NodeStageSign = tech.StageSign;
                    bopContentInfo.NodeStageSignDesc = ((StageSigns)tech.StageSign).ToString();
                    string url = ConfigHelper.GetAppSetting("App", "GetAppUrl");
                    bopContentInfo.TechniqueExplain = tech.TechniqueExplain.Replace("../", url + @"/");
                }
                return bopContentInfo;
            }
            var bop = await _bopNodeRepository.GetAll().Include(c => c.BopContents).FirstOrDefaultAsync(p => p.Id == bopNode.Id);
            if (bop != null)
            {
                if (bop != null)
                {
                    bopContentInfo.NodeDrawingNo = bop.NodeDrawingNo;
                    bopContentInfo.NodeName = bop.NodeName;
                    if (bop.BopContents != null)
                    {
                        bopContentInfo.ContentId = bop.BopContents.Id;
                        bopContentInfo.Remark = bop.BopContents.Remark;
                    }
                }
                if (tech != null)
                {
                    bopContentInfo.ProcessCode = bop.ProcessCode;
                    bopContentInfo.ProcessName = tech.TechniqueName;
                    bopContentInfo.NodeStageSign = tech.StageSign;
                    bopContentInfo.NodeStageSignDesc = ((StageSigns)tech.StageSign).ToString();
                    bopContentInfo.PadName = bop.PadName;
                    bopContentInfo.ExportDate = bop.ExportDate;
                    bopContentInfo.RelationDate = bop.RelationDate;
                    bopContentInfo.TechniqueExplain = tech.TechniqueExplain;
                }
            }
            return bopContentInfo;
        }
        /// <summary>
        /// 工艺工程规程文件首页
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<RTechFileHeaderDto> GetTechFileHeader(Guid id)
        {
            //根据节点工艺规程编号去查询绑定的文档
            var datalist = new RTechFileHeaderDto();
            var tech = await _techniqueEntityRepository.FirstOrDefaultAsync(x => x.Id == id);
            if (tech != null)
            {
                datalist.TechniqueEntityId = id;
                datalist.TechniqueName = tech.TechniqueName;
                datalist.TechniqueNumber = tech.TechniqueNumber;
                datalist.TechniqueAuthor = tech.TechniqueAuthor;
                datalist.TechniqueAuthorTime = tech.TechniqueAuthor;
                datalist.Proofreader = tech.Proofreader;
                datalist.ProofreaderTime = tech.ProofreaderTime;
                datalist.Reviewer = tech.Reviewer;
                datalist.ReviewerTime = tech.ReviewerTime;
                datalist.Inspector = tech.Inspector;
                datalist.InspectorTime = tech.InspectorTime;
                datalist.Certifier = tech.Certifier;
                datalist.CertifierTime = tech.CertifierTime;
                datalist.CompileTime = tech.CompileTime;
                datalist.SystemCode = tech.SystemCode;
                datalist.ProductCode = tech.ProductCode;
                datalist.ModuleCode = tech.ModuleCode;
                datalist.ModuleName = tech.ModuleName;
                datalist.StageSign = tech.StageSign;
                datalist.StageSignDesc = ((StageSigns)tech.StageSign).ToString();
                datalist.TechniqueType = tech.TechniqueType;
                datalist.TechniqueCharacter = tech.TechniqueCharacter;
                datalist.Shape = tech.Shape;
                datalist.SecretDegree = tech.SecretDegree;
                datalist.UseUnit = tech.UseUnit;
                datalist.UseTime = tech.UseTime;
                datalist.BasisFile = tech.BasisFile;
                datalist.IssueUnit = tech.IssueUnit;
                datalist.TechniqueExplain = tech.TechniqueExplain;
                datalist.Remark = tech.Remark;
                datalist.Model = GeModelById(id);
                datalist.LotNo = GetLotNoByTechId(id);
            }
            return datalist;
        }
        ///// <summary>
        ///// 根据工艺规程编号获取发次
        ///// </summary>
        ///// <param name="techniqueNumber"></param>
        ///// <returns></returns>
        //public string GetLotNoByTechtechniqueNumber(string techniqueNumber)
        //{
        //    var tech = _techniqueEntityRepository.FirstOrDefault(x => x.TechniqueNumber == techniqueNumber);
        //    var bopNode = _bopNodeRepository.FirstOrDefault(x => x.TechniqueEntityId == tech.Id);
        //    if (bopNode != null)
        //    {
        //        return _bopDescRepository.FirstOrDefault(d => d.Id == bopNode.BopDescId).LotNo;
        //    }
        //    else
        //    {
        //        return "";
        //    }
        //}
        /// <summary>
        /// 根据Id获取型号
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        private string GeModelById(Guid id)
        {
            //var tech = _techniqueEntityRepository.FirstOrDefault(x => x.Id == id);
            var bopNode = _bopNodeRepository.FirstOrDefault(x => x.TechniqueEntityId == id);
            if (bopNode != null)
            {
                var modelId = _bopDescRepository.FirstOrDefault(d => d.Id == bopNode.BopDescId).ModelId;
                if (modelId != null)
                {
                    return _sysCodeRepository.FirstOrDefault(s => s.Id == modelId).Description; ;
                }
                else
                {
                    return "";
                }
            }
            else
            {
                return "";
            }
        }
        /// <summary>
        /// 循环生成工序和工步树
        /// </summary>
        /// <param name="id"></param>
        public List<TreeClass> GetBindWorkStepByNumber(Guid id)
        {
            ////获取节点信息的工艺规程编码
            //var tech = _techniqueEntityRepository.FirstOrDefault(x => x.Id == id);
            //Guid techId = tech.Id;
            //获取工序和工步的信息，并做相应的排序
            var processesList = _processesEntityRepository.GetAllIncluding(p => p.WorkStepEntities).Where(p => p.TechniqueEntityId == id).OrderBy(n => n.ProcessesSequence);
            //循环遍历，往Node里面赋值
            foreach (var item in processesList)
            {
                TreeClass tree = new TreeClass();
                tree.Id = item.Id;
                tree.ParentId = id;
                tree.NodeDrawingNo = "工序" + item.ProcessesSequence.ToString() + " ";
                tree.NodeName = item.ProcessesName;
                tree.IsRelation = 0;
                tree.NodeLevel = 8;
                item.WorkStepEntities = item.WorkStepEntities.OrderBy(r => r.WorkStepNumber).ToList();
                //查询工步
                foreach (var witem in item.WorkStepEntities)
                {
                    TreeClass wtree = new TreeClass();
                    wtree.Id = witem.Id;
                    wtree.ParentId = item.Id;
                    wtree.NodeDrawingNo = "工步" + item.ProcessesSequence.ToString();// + "-"+ witem.WorkStepNumber.ToString();
                    wtree.NodeName = witem.WorkStepNumber.ToString();//witem.WorkStepName  这个值数据库有问题
                    wtree.IsRelation = 0;
                    wtree.NodeLevel = 9;
                    tree.children.Add(wtree);
                }
                treeNodes.Add(tree);
            }
            return treeNodes;
        }
        /// <summary>
        /// 复制工艺规程
        /// </summary>
        /// <param name="sourceId"></param>
        public bool CopyTechtechnique(Guid sourceId)
        {
            //前台选择一本工艺规程 然后 复制其下 工序 工步 动态表 实体表 数据
            try
            {
                //先获取工艺规程 然后复制数据
                var tech = _techniqueEntityRepository.Get(sourceId);
                var techTemp = _techniqueEntityRepository.FirstOrDefault(d => d.TechniqueNumber == tech.TechniqueNumber && d.Edition == "" && tech.FileStatus == FileStatus.新增);
                if (techTemp == null)
                {
                    Dictionary<Guid, Guid> dicMap = new Dictionary<Guid, Guid>(); //记录变更前的id  变更后的id 后期 好根据这个记录来修改工艺路线的信息
                    tech.Id = Guid.NewGuid();
                    tech.Edition = "";
                    tech.FileStatus = 0;
                    tech.ProcessesEntities = null;
                    tech.CreationTime = DateTime.Now;
                    tech.Property = TechAttribute.规程复制;
                    _techniqueEntityRepository.Insert(tech);
                    var newProcessesList = _processesEntityRepository.GetAllIncluding(p => p.WorkStepEntities).Where(p => p.TechniqueEntityId == sourceId);
                    //复制工序信息 
                    foreach (var item in newProcessesList)
                    {
                        item.TechniqueEntityId = tech.Id;
                        var guid = Guid.NewGuid();
                        dicMap.Add(item.Id, guid);
                        item.Id = guid;
                        _processesEntityRepository.Insert(item);
                        //复制工步信息 
                        foreach (var temp in item.WorkStepEntities)
                        {
                            var workGuid = Guid.NewGuid();
                            dicMap.Add(temp.Id, workGuid);
                            var loadList = _loadPieceRepository.GetAll().Where(d => d.WorkStepEntityId == temp.Id);
                            var makeList = _makeResourcesEntityRepository.GetAll().Where(d => d.WorkStepEntityId == temp.Id);
                            var videoList = _videoEntityRepository.GetAll().Where(d => d.WorkStepEntityId == temp.Id);
                            foreach (var load in loadList)
                            {
                                load.Id = Guid.NewGuid();
                                load.WorkStepEntityId = workGuid;
                                _loadPieceRepository.Insert(load);
                            }
                            foreach (var make in makeList)
                            {
                                make.Id = Guid.NewGuid();
                                make.WorkStepEntityId = workGuid;
                                _makeResourcesEntityRepository.Insert(make);
                            }
                            foreach (var video in videoList)
                            {
                                video.Id = Guid.NewGuid();
                                video.WorkStepEntityId = workGuid;
                                _videoEntityRepository.Insert(video);
                            }

                            temp.Id = workGuid;
                            temp.ProcessesEntityId = item.Id;
                            temp.TechniqueEntityId = tech.Id;
                            _workStepEntityRepository.Insert(temp);
                        }
                    }
                    var workList = _workStepEntityRepository.GetAll().Where(d => d.TechniqueEntityId == sourceId).Select(d => d.Id);
                    var tableData = _tableBaseEntity.GetAllIncluding(a => a.RecordRequirements, b => b.InspectionSignature, c => c.MeasuredResult, d => d.Environment, e => e.MultiMedia).Where(d => workList.Contains(d.WorkStepEntityId));
                    //复制90个关联表信息 
                    foreach (var item in tableData)
                    {
                        ConvertFormBase cFormbase = new ConvertFormBase(Guid.NewGuid(), item.FormName, item.SerialNum, dicMap[item.WorkStepEntityId], dicMap[item.ProcessesEntityId], item.Sort, item.Deptment,
                        item.ParentProductNum, item.ParentProductNum_DisplayName,
                        item.ParentProductNum_Enable, item.ParentProductNum_Show, item.ParentProductNum_Property, item.ParentProductName, item.ParentProductName_DisplayName, item.ParentProductName_Enable, item.ParentProductName_Show,
                        item.ParentProductName_Property, item.FisrtDrawingNum, item.FisrtDrawingNum_DisplayName, item.FisrtDrawingNum_Enable, item.FisrtDrawingNum_Show, item.FisrtDrawingNum_Property,
                        item.FirstDrawingName, item.FirstDrawingName_DisplayName, item.FirstDrawingName_Enable, item.FirstDrawingName_Show, item.FirstDrawingName_Property,
                        item.SecondDrawingNum, item.SecondDrawingNum_DisplayName, item.SecondDrawingNum_Enable, item.SecondDrawingNum_Show, item.SecondDrawingNum_Property,
                        item.SecondDrawingName, item.SecondDrawingName_DisplayName, item.SecondDrawingName_Enable, item.SecondDrawingName_Show, item.SecondDrawingName_Property,
                        item.ProductNum, item.ProductNum_DisplayName, item.ProductNum_Enable, item.ProductNum_Show, item.ProductNum_Property,
                        item.Model, item.Model_DisplayName, item.Model_Enable, item.Model_Show, item.Model_Property, item.RecordElement, item.RecordElement_DisplayName, item.RecordElement_Enable,
                        item.RecordElement_Show, item.RecordElement_Property, item.RecordItem, item.RecordItem_DisplayName, item.RecordItem_Enable, item.RecordItem_Show, item.RecordItem_Property,
                        item.ToolUsed, item.ToolUsed_DisplayName, item.ToolUsed_Enable, item.ToolUsed_Show, item.ToolUsed_Property, item.AbnormalRecord, item.AbnormalRecord_DisplayName,
                        item.AbnormalRecord_Enable, item.AbnormalRecord_Show, item.AbnormalRecord_Property, item.Certificate, item.Certificate_DisplayName, item.Certificate_Enable,
                        item.Certificate_Show, item.Certificate_Property, item.SecondToolUsed, item.SecondToolUsed_DisplayName, item.SecondToolUsed_Enable, item.SecondToolUsed_Show,
                        item.SecondToolUsed_Property, item.ThirdToolUsed, item.ThirdToolUsed_DisplayName, item.ThirdToolUsed_Enable, item.ThirdToolUsed_Show, item.ThirdToolUsed_Property,
                        item.ParamCode, item.ParamCode_DisplayName, item.ParamCode_Enable, item.ParamCode_Show, item.ParamCode_Property

                        );
                        if (item.InspectionSignature != null)
                        {
                            cFormbase.InspectionSignature = cFormbase.SetInspectionSignature(item.InspectionSignature);
                        }
                        if (item.RecordRequirements != null)
                        {
                            cFormbase.RecordRequirements = cFormbase.SetRecordRequirements(item.RecordRequirements);
                        }
                        if (item.MultiMedia != null)
                        {
                            cFormbase.MultiMedia = cFormbase.SetMultiMedia(item.MultiMedia);
                        }
                        if (item.MeasuredResult != null)
                        {
                            cFormbase.MeasuredResult = cFormbase.SetMeasuredResult(item.MeasuredResult);
                        }
                        if (item.Environment != null)
                        {
                            cFormbase.Environment = cFormbase.SetEnvironment(item.Environment);
                        }
                        _convertFormBaseEntity.Insert(cFormbase);
                    }
                    var bopNode = _bopNodeRepository.GetAll().Where(d => d.TechniqueEntityId == sourceId).FirstOrDefault();
                    //复制路线信息
                    if (bopNode != null)
                    {
                        dicMap.Add(bopNode.Id, tech.Id);
                        //更改关系表
                        var lineList = _processLineRepository.GetAll().Where(d => dicMap.Keys.Contains(d.PPtr));
                        foreach (var item in lineList)
                        {
                            if (dicMap.ContainsKey(item.PPtr))
                            {
                                item.PPtr = dicMap[item.PPtr];

                            }
                            if (dicMap.ContainsKey(item.From))
                            {
                                item.From = dicMap[item.From];

                            }
                            if (dicMap.ContainsKey(item.To))
                            {
                                item.To = dicMap[item.To];
                            }
                            item.Id = new Guid();
                            item.BopDescId = null;
                            _processLineRepository.Insert(item);
                        }

                    }
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch (Exception ex)
            {
                return false;
            }

        }
        [Microsoft.AspNetCore.Mvc.DisableRequestSizeLimit]
        /// <summary>
        /// 批量回传
        /// </summary>
        /// <param name="file"></param>
        /// <param name="md5"></param>
        /// <returns></returns>
       
        public async Task<ResultMessage> UploadBop(IFormFile file)
        {
            ResultMessage resultMessage = new ResultMessage();
            string uniqueFileName = null;

            if (file != null)
            {
                string[] formatArray = { ".zip", ".7z" };
                //文件格式
                var fileExtension = Path.GetExtension(file.FileName);
                if (!formatArray.Contains(fileExtension))
                {

                    resultMessage.code = 1;
                    resultMessage.Message = "上传文件格式错误!";
                    return resultMessage;

                }
                string jsonName = "";

                var treeVersion = new TreeVersionLog();
                TreeVersionLog versionLog = new TreeVersionLog();
                long treeEdition = 0;
                //文件名称
                var fileTextName = file.FileName.Split('.')[0];
                if (fileTextName.Contains("_"))
                {
                    //获取文件名称 然后分割 第一层是树 数据 第二层是各个工艺数据
                    jsonName = fileTextName.Substring(0, fileTextName.Length - 2);
                    string keyWord = "_";
                    int index = 0;
                    int count = 0; //统计下划线个数  格式   型号_发次_版本.zip 有二个下划线_
                    while ((index = fileTextName.IndexOf(keyWord, index)) != -1)
                    {
                        count++;
                        index = index + keyWord.Length;
                    }
                    if (count == 2)
                    {
                        #region 版本控制
                        var array = fileTextName.Split('_');
                        var modelName = array[0];
                        var lotName = array[1];
                        var edtion = Convert.ToInt64(array[2]);
                        var bopDesc = await _bopDescRepository.FirstOrDefaultAsync(d => d.Model == modelName && d.LotNo == lotName);
                        //先查询库中是否存在 存在才可以解析
                        if (bopDesc != null)
                        {
                            //每次导出 都会更新一下版本 所以这里看看版本是否 正确 只能按序号统计 1 ，2，3..  
                            treeVersion = await _treeVersionLogRepository.FirstOrDefaultAsync(d => d.ModelId == bopDesc.ModelId && d.LotNoId == bopDesc.LotNoId && d.Type == 1);
                            if (treeVersion != null)
                            {
                                treeEdition = treeVersion.Version;
                                if (edtion != (treeEdition + 1))
                                {
                                    resultMessage.code = 1;
                                    resultMessage.Message = "当前版本不符合,只能接收版本" + (treeEdition + 1).ToString();
                                    return resultMessage;

                                }
                                else
                                {
                                    treeVersion.Version = (treeEdition + 1);
                                }
                            }
                            else
                            {
                                if (edtion == 1)
                                {
                                    //TreeVersionLog versionLog = new TreeVersionLog();
                                    versionLog.ModelId = bopDesc.ModelId;
                                    versionLog.LotNoId = bopDesc.LotNoId;
                                    versionLog.Type = 1;
                                    versionLog.Version = 1;
                                    //await _treeVersionLogRepository.InsertAsync(versionLog);
                                }
                                else
                                {
                                    resultMessage.code = 1;
                                    resultMessage.Message = "导入数据包版本不正确";
                                    return resultMessage;

                                }
                            }
                        }
                        else
                        {
                            resultMessage.code = 1;
                            resultMessage.Message = "导入数据包名称不正确";
                            return resultMessage;

                        }
                        #endregion
                    }
                    else
                    {
                        resultMessage.code = 1;
                        resultMessage.Message = "导入数据包名称不正确";
                        return resultMessage;
                    }
                }
                else
                {
                    resultMessage.code = 1;
                    resultMessage.Message = "导入数据包名称不正确";
                    return resultMessage;
                }


                //读取文件保存的根目录
                string fileSaveRootDir = ConfigHelper.GetAppSetting("App", "BopFileRootPath");


                //文件保存的路径(应用的工作目录+文件夹相对路径);
                string fileSavePath = Environment.CurrentDirectory + "/wwwroot/" + fileSaveRootDir;
                if (!Directory.Exists(fileSavePath))
                {
                    Directory.CreateDirectory(fileSavePath);
                }
                uniqueFileName = jsonName + fileExtension;




                string filePath = Path.Combine(fileSavePath, uniqueFileName);
                using (var fileStream = new FileStream(filePath, FileMode.Create))
                {
                    file.CopyTo(fileStream);
                    fileStream.Flush();
                }
                //获得当前文件夹名称
                var fileSave = uniqueFileName.Split('.')[0];

                String DateStr = System.DateTime.Now.ToString("yyyyMMdd");

                //解压文件
                (new FastZip()).ExtractZip(@filePath, @fileSavePath + "/" + fileSave + "/" + DateStr, "");
                //   var josnname = file.FileName.Split('.')[0];
                var Json = fileSavePath + "/" + fileSave + "/" + DateStr + "/" + jsonName + ".json";


                var directory = new DirectoryInfo(fileSavePath + "/" + fileSave + "/" + DateStr + "/");
                var logFiles = directory.GetFiles("*.json", SearchOption.AllDirectories).ToList();
                List<BackTaskFormat> Tasks = new List<BackTaskFormat>();
                for (int i = 0; i < logFiles.Count; i++)
                {
                    var techName = logFiles[i].Name.Split('.')[0];
                    if (techName.Replace("_", "") != jsonName.Replace("_", ""))
                    {
                        BackTaskFormat backTask = new BackTaskFormat();
                        backTask.TechniqueNum = techName;
                        backTask.FilePath = fileSavePath + "/" + fileSave + "/" + DateStr + "/" + techName + "/" + techName + "/" + techName + ".json";
                        Tasks.Add(backTask);
                    }
                }
                BackTaskInput taskInput = new BackTaskInput(); 
                taskInput.BackTask = Tasks;
                 
                //解析文件
                string message = await _techProcess.BatchAnalyJson(taskInput);
                if (!string.IsNullOrEmpty(message))
                {
                    resultMessage.code = 1;
                    resultMessage.Message = message;
                    return resultMessage;
                }

                //递归复制文件 将 各个 规程的文件 复制到 系统中uploadfile文件夹中
                string fileBopRootDir = ConfigHelper.GetAppSetting("App", "FileRootPath");

                for (int i = 0; i < Tasks.Count; i++)
                {
                    string sourcePatch = fileSavePath + "/" + fileSave + "/" + DateStr + "/" + Tasks[i].TechniqueNum + "/" + Tasks[i].TechniqueNum + "/";
                    string srcPatch = Environment.CurrentDirectory + "/wwwroot/" + fileBopRootDir + "/" + Tasks[i].TechniqueNum + "/";
                    if (!Directory.Exists(srcPatch))
                    {
                        Directory.CreateDirectory(srcPatch);
                        if (CopyDir(sourcePatch, srcPatch))
                        {
                        }
                        else
                        {
                            throw new UserFriendlyException("拷贝文件失败！");
                        }
                    }
                    else
                    {
                        DirectoryInfo root = new DirectoryInfo(sourcePatch);
                        var dics = root.GetDirectories();
                        for (int k = 0; k < dics.Length; k++)
                        {
                            string tempPath = srcPatch + dics[k].Name + "/";

                            if (dics[k].Name == "Exception")
                            {
                                string pathEx = dics[k].FullName + "/picture" + "/";
                                if (Directory.Exists(pathEx))
                                {
                                    string exceptionpath = Environment.CurrentDirectory + "/wwwroot/" + "/Inspection/";
                                    if (CopyDir(pathEx, exceptionpath))
                                    {
                                    }
                                    else
                                    {
                                        throw new UserFriendlyException("拷贝文件失败！");
                                    }
                                }
                            }
                            else
                            {
                                if (!Directory.Exists(tempPath))
                                {
                                    Directory.CreateDirectory(srcPatch);
                                }
                                if (CopyDir(dics[k].FullName, tempPath))
                                {
                                }
                                else
                                {
                                    throw new UserFriendlyException("拷贝文件失败！");
                                }
                            }
                        }
                        //Directory.Delete(srcPatch, true);
                    }
                }
                resultMessage.code = 0;
                resultMessage.Message = jsonName + "上传成功!";
                if (treeVersion != null) await _treeVersionLogRepository.UpdateAsync(treeVersion);
                else await _treeVersionLogRepository.InsertAsync(versionLog);
                return resultMessage;
                ////获取传入文件的md5值
                //var md = GetMD5HashFromFile(filePath);
                ////判断上传的文件的md5是否相同
                //if (md == md5)
                //{


                //}
                //else
                //{
                //    resultMessage.code = 1;
                //    resultMessage.Message = "Md5值不符,请重新上传";
                //    return resultMessage;

                //}

            }
            else
            {
                resultMessage.code = 1;
                resultMessage.Message = "文件不能为空";
                return resultMessage;
            }
        }


        /// <summary>
        /// 批量回传
        /// </summary>
        /// <param name="file"></param>
        /// <param name="md5"></param>
        /// <returns></returns>
        [UnitOfWork(false)]
        public async Task<ResultMessage> UploadBigBop(string file)
        {
            ResultMessage resultMessage = new ResultMessage();
            string uniqueFileName = null;

            //曲冰修改20220902
            if (!string.IsNullOrEmpty(file))
            {
                string[] formatArray = { ".zip", ".7z" };
                //文件格式
                //曲冰修改20220902
                var fileExtension = Path.GetExtension(file);
                if (!formatArray.Contains(fileExtension))
                {

                    resultMessage.code = 1;
                    resultMessage.Message = "上传文件格式错误!";
                    return resultMessage;

                }
                string jsonName = "";

                var treeVersion = new TreeVersionLog();
                TreeVersionLog versionLog = new TreeVersionLog();
                long treeEdition = 0;
                //文件名称
                var fileTextName = file.Split('.')[0];
                if (fileTextName.Contains("_"))
                {
                    //获取文件名称 然后分割 第一层是树 数据 第二层是各个工艺数据
                    //jsonName = fileTextName.Substring(0, fileTextName.Length - 2);
                    jsonName = fileTextName.Substring(0, fileTextName.LastIndexOf("_"));
                    string keyWord = "_";
                    int index = 0;
                    int count = 0; //统计下划线个数  格式   型号_发次_版本.zip 有二个下划线_
                    while ((index = fileTextName.IndexOf(keyWord, index)) != -1)
                    {
                        count++;
                        index = index + keyWord.Length;
                    }
                    if (count == 2)
                    {
                        #region 版本控制
                        var array = fileTextName.Split('_');
                        var modelName = array[0];
                        var lotName = array[1];
                        var edtion = Convert.ToInt64(array[2]);
                        var bopDesc = await _bopDescRepository.FirstOrDefaultAsync(d => d.Model == modelName && d.LotNo == lotName);
                        //先查询库中是否存在 存在才可以解析
                        if (bopDesc != null)
                        {
                            //每次导出 都会更新一下版本 所以这里看看版本是否 正确 只能按序号统计 1 ，2，3..  
                            treeVersion = await _treeVersionLogRepository.FirstOrDefaultAsync(d => d.ModelId == bopDesc.ModelId && d.LotNoId == bopDesc.LotNoId && d.Type == 1);
                            if (treeVersion != null)
                            {
                                treeEdition = treeVersion.Version;
                                if (edtion != (treeEdition + 1))
                                {
                                    resultMessage.code = 1;
                                    resultMessage.Message = "当前版本不符合,只能接收版本" + (treeEdition + 1).ToString();
                                    return resultMessage;

                                }
                                else
                                {
                                    treeVersion.Version = (treeEdition + 1);
                                }
                            }
                            else
                            {
                                if (edtion == 1)
                                {
                                    //TreeVersionLog versionLog = new TreeVersionLog();
                                    versionLog.ModelId = bopDesc.ModelId;
                                    versionLog.LotNoId = bopDesc.LotNoId;
                                    versionLog.Type = 1;
                                    versionLog.Version = 1;
                                    //await _treeVersionLogRepository.InsertAsync(versionLog);
                                }
                                else
                                {
                                    resultMessage.code = 1;
                                    resultMessage.Message = "导入数据包版本不正确";
                                    return resultMessage;

                                }
                            }
                        }
                        else
                        {
                            resultMessage.code = 1;
                            resultMessage.Message = "导入数据包名称不正确";
                            return resultMessage;

                        }
                        #endregion
                    }
                    else
                    {
                        resultMessage.code = 1;
                        resultMessage.Message = "导入数据包名称不正确";
                        return resultMessage;
                    }
                }
                else
                {
                    resultMessage.code = 1;
                    resultMessage.Message = "导入数据包名称不正确";
                    return resultMessage;
                }


                //读取文件保存的根目录
                string fileSaveRootDir = ConfigHelper.GetAppSetting("App", "BopFileRootPath");
                //压缩包保存目录
                //曲冰修改20220902
                string fileSaveBigRootDir = ConfigHelper.GetAppSetting("App", "BigFileRootPath");
                //文件保存的路径(应用的工作目录+文件夹相对路径);
                //曲冰修改20220902
                string fileSavePath = Environment.CurrentDirectory + "/wwwroot/" + fileSaveBigRootDir;
                //if (!Directory.Exists(fileSavePath))
                //{
                //    Directory.CreateDirectory(fileSavePath);
                //}
                uniqueFileName = jsonName + fileExtension;
                //string filePath = Path.Combine(fileSavePath, uniqueFileName);
                //using (var fileStream = new FileStream(filePath, FileMode.Create))
                //{
                //    file.CopyTo(fileStream);
                //    fileStream.Flush();
                //}
                //获得当前文件夹名称
                var fileSave = uniqueFileName.Split('.')[0];

                String DateStr = System.DateTime.Now.ToString("yyyyMMdd");

                string FilePath = Environment.CurrentDirectory + "/wwwroot/" + fileSaveRootDir + "/" + jsonName + "/" + DateStr;
                //曲冰修改20220902
                if (!ZipOpen(fileSavePath + "/" + file, FilePath, true))
                {
                    resultMessage.code = 1;
                    resultMessage.Message = "解压文件错误";
                    return resultMessage;
                }
                //解压文件
                //(new FastZip()).ExtractZip(@filePath, @fileSavePath + "/" + fileSave + "/" + DateStr, "");
                //   var josnname = file.FileName.Split('.')[0];
                var Json = fileSavePath + "/" + fileSave + "/" + DateStr + "/" + jsonName + ".json";
                var directory = new DirectoryInfo(FilePath + "/");
                var logFiles = directory.GetFiles("*.json", SearchOption.AllDirectories).ToList();
                List<BackTaskFormat> Tasks = new List<BackTaskFormat>();
                for (int i = 0; i < logFiles.Count; i++)
                {
                    var techName = logFiles[i].Name.Split('.')[0];
                    if (techName.Replace("_", "") != jsonName.Replace("_", ""))
                    {
                        BackTaskFormat backTask = new BackTaskFormat();
                        backTask.TechniqueNum = techName;
                        //曲冰修改
                        backTask.FilePath = Environment.CurrentDirectory + "/wwwroot/" + fileSaveRootDir + "/" + fileSave + "/" + DateStr + "/" + techName + "/" + techName + "/" + techName + ".json";
                        Tasks.Add(backTask);
                    }
                }
                BackTaskInput taskInput = new BackTaskInput();
                taskInput.BackTask = Tasks;

                //解析文件
                string message = await _techProcess.BatchAnalyJson(taskInput);
                if (!string.IsNullOrEmpty(message))
                {
                    resultMessage.code = 1;
                    resultMessage.Message = message;
                    return resultMessage;
                }

                //递归复制文件 将 各个 规程的文件 复制到 系统中uploadfile文件夹中
                string fileBopRootDir = ConfigHelper.GetAppSetting("App", "FileRootPath");
                
                for (int i = 0; i < Tasks.Count; i++)
                {
                    //曲冰修改
                    string sourcePatch = Environment.CurrentDirectory + "/wwwroot/" + fileSaveRootDir + "/" + fileSave + "/" + DateStr + "/" + Tasks[i].TechniqueNum + "/" + Tasks[i].TechniqueNum + "/";
                    string srcPatch = Environment.CurrentDirectory + "/wwwroot/" + fileBopRootDir + "/" + Tasks[i].TechniqueNum + "/";
                    if (!Directory.Exists(srcPatch))
                    {
                        Directory.CreateDirectory(srcPatch);
                        if (CopyDir(sourcePatch, srcPatch))
                        {
                        }
                        else
                        {
                            throw new UserFriendlyException("拷贝文件失败！");
                        }
                    }
                    else
                    {
                        DirectoryInfo root = new DirectoryInfo(sourcePatch);
                        var dics = root.GetDirectories();
                        for (int k = 0; k < dics.Length; k++)
                        {
                            string tempPath = srcPatch + dics[k].Name + "/";

                            if (dics[k].Name == "Exception")
                            {
                                string pathEx = dics[k].FullName + "/picture" + "/";
                                if (Directory.Exists(pathEx))
                                {
                                    string exceptionpath = Environment.CurrentDirectory + "/wwwroot/" + "/Inspection/";
                                    if (CopyDir(pathEx, exceptionpath))
                                    {
                                    }
                                    else
                                    {
                                        throw new UserFriendlyException("拷贝文件失败！");
                                    }
                                }
                            }
                            else
                            {
                                if (!Directory.Exists(tempPath))
                                {
                                    Directory.CreateDirectory(srcPatch);
                                }
                                if (CopyDir(dics[k].FullName, tempPath))
                                {
                                }
                                else
                                {
                                    throw new UserFriendlyException("拷贝文件失败！");
                                }
                            }
                        }
                        //Directory.Delete(srcPatch, true);
                    }
                }
                if (resultMessage.code == 0)
                {
                    resultMessage.code = 0;
                    resultMessage.Message = jsonName + "上传成功!";
                    using (var unitOfWork = _unitOfWorkManager.Begin(System.Transactions.TransactionScopeOption.RequiresNew))
                    {
                        if (treeVersion != null) await _treeVersionLogRepository.UpdateAsync(treeVersion);
                        else await _treeVersionLogRepository.InsertAsync(versionLog);
                        unitOfWork.Complete();
                    }
                    //导入成功后删除压缩包
                    if (File.Exists(fileSavePath + "/" + file))
                    {
                        File.Delete(fileSavePath + "/" + file);
                    }
                    return resultMessage;
                }
                else
                {
                    resultMessage.code = 1;
                    resultMessage.Message = "上传失败";
                    return resultMessage;
                }
               
            }
            else
            {
                resultMessage.code = 1;
                resultMessage.Message = "文件不能为空";
                return resultMessage;
            }
        }

        private bool ZipOpen(string zipPath, string filePath, bool v)
        {
            try
            {
                StaticOperation.UnZip(zipPath, filePath, null, true);
                return true;
            }
            catch(Exception ex)
            {
                ConfigHelper.CreateLogText("解压文件:" + "@filePath:" + @filePath + " 错误信息:"+ex.ToString());
                return false;

            }
        }

        private string GetMD5HashFromFile(string fileName)
        {
            try
            {
                FileStream file = new FileStream(fileName, FileMode.Open);
                MD5 md5 = new MD5CryptoServiceProvider();
                byte[] retVal = md5.ComputeHash(file);
                file.Close();
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < retVal.Length; i++)
                {
                    sb.Append(retVal[i].ToString("x2"));
                }
                return sb.ToString();
            }
            catch (Exception ex)
            {
                throw new Exception("GetMD5HashFromFile() fail,error:" + ex.Message);
            }
        }
        //拷贝文件
        private bool CopyDir(string srcPath, string aimPath)
        {
            try
            {
                // 检查目标目录是否以目录分割字符结束如果不是则添加
                if (aimPath[aimPath.Length - 1] != System.IO.Path.DirectorySeparatorChar)
                {
                    aimPath += System.IO.Path.DirectorySeparatorChar;
                }
                // 判断目标目录是否存在如果不存在则新建
                if (!System.IO.Directory.Exists(aimPath))
                {
                    System.IO.Directory.CreateDirectory(aimPath);
                }
                // 得到源目录的文件列表，该里面是包含文件以及目录路径的一个数组
                // 如果你指向copy目标文件下面的文件而不包含目录请使用下面的方法
                // string[] fileList = Directory.GetFiles（srcPath）；
                string[] fileList = System.IO.Directory.GetFileSystemEntries(srcPath);
                // 遍历所有的文件和目录
                foreach (string file in fileList)
                {
                    // 先当作目录处理如果存在这个目录就递归Copy该目录下面的文件
                    if (System.IO.Directory.Exists(file))
                    {
                        CopyDir(file, aimPath + System.IO.Path.GetFileName(file));
                    }
                    // 否则直接Copy文件
                    else
                    {
                        System.IO.File.Copy(file, aimPath + System.IO.Path.GetFileName(file), true);
                    }
                }
                return true;
            }
            catch (Exception ex)
            {
                //return false;
                throw new Exception(ex.Message);
            }
        }



    }
}




